/*********************************
*-- 33 KDH Knieja ---------------*
*-- im. Harcerzy Września 1939 --*
*-- autor: Marcin Rzepisko ------*
*-- data: 2013-11-11 ------------*
**********************************/

package net.kdh.knieja.dao.polaczenie;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.kdh.knieja.model.wspolne.wyjatki.BladWarstwyDaoWyjatek;

/**
 *
 * @author rz.marcin@gmail.com
 */
public class PolaczenieBazy {

    private String DRIVER;
    private String URL;
    private String USER;
    private String PASS;

    private Connection connection;
    private Statement statement;

    public PolaczenieBazy(ParametryPolaczenia parametry) {
        DRIVER = parametry.getDRIVER();
        USER = parametry.getDaneDostepu().getLogin();
        PASS = parametry.getDaneDostepu().getHaslo();
        URL = parametry.getConnectionString();
    }
    
    /**
     * Zwraca obiekt {@link Statement} do operacji na bazie danych 
     * Jeśli nie istnieje inicjalizuje połączenie z bazą danych
     *
     * @return Statement
     * @throws BladWarstwyDaoWyjatek
     */
    public final void startTransaction() throws BladWarstwyDaoWyjatek {
        try {
            getStatement();
            statement.executeQuery("START TRANSACTION");
        } catch (SQLException ex) {
            System.out.println("Nie udalo się rozpocząć tranzakcji:\n" + ex.getLocalizedMessage());
            throw new BladWarstwyDaoWyjatek("PolaczenieBazy.startTransaction()", ex);
        }
    }
    
    public final Statement getStatement() throws BladWarstwyDaoWyjatek {
        if (statement == null) {
            try { //connect
                connect();
            } catch (ClassNotFoundException ex) {
                System.err.println("Nie znaleziono sterownika " + DRIVER + "\n" + ex.getLocalizedMessage());
                throw new BladWarstwyDaoWyjatek("PolaczenieBazy.wykonajQuery().connect()", ex);
            } catch (InstantiationException ex) {
                System.err.println("Nie można utworzyć instancji dla sterownika " + DRIVER + "\n" + ex.getLocalizedMessage());
                throw new BladWarstwyDaoWyjatek("PolaczenieBazy.wykonajQuery().connect()", ex);
            } catch (IllegalAccessException ex) {
                System.err.println("Brak dostępu" + "\n" + ex.getLocalizedMessage());
                throw new BladWarstwyDaoWyjatek("PolaczenieBazy.wykonajQuery().connect()", ex);
            } catch (SQLException ex) {
                System.out.println("Błąd SQL" + "\n" + ex.getLocalizedMessage());
                throw new BladWarstwyDaoWyjatek("PolaczenieBazy.wykonajQuery().connect()", ex);
            } // connect
            
            try {
                initStatement();
            } catch (SQLException ex) {
                System.err.println("Błąd SQL, initStatement()" + "\n" + ex.getLocalizedMessage());
                throw new BladWarstwyDaoWyjatek("PolaczenieBazy.wykonajQuery().initStatement()", ex);
            }
        }
        return statement;
    }
    
    private void initStatement() throws SQLException {
        statement = connection.createStatement();
    }
    
    public final void commit() throws SQLException {
        statement.executeQuery("COMMIT");
    }
    
    private void connect() throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException {
        if (connection == null || connection.isClosed()) {
            System.out.println("-- Łączenie z bazą danych @" + URL);
            System.out.println("   |-- Inicjalizacja sterownika " + DRIVER);
            Class.forName(DRIVER).newInstance();
            System.out.println("   |-- Tworzenie połączenia dla użytkownika " + USER + "...");
            connection = DriverManager.getConnection(URL, USER, PASS);
            System.out.println("-- Połączono! " + connection.toString());
        } else {
            System.err.println("-- Połącznie już jest otwarte!");
        }
    }
    
    public void disconnect() throws SQLException {
        if (connection != null) {
            if (statement != null) {
                System.out.println("-- Usuwanie zapisanych zapytań...");
                statement.close();
            }
            System.out.println("-- Zapisywanie zmian tranzakcji...");
            connection.commit();
            System.out.println("-- Zamykanie połączenia...");
            connection.close();
            System.out.println("-- Pomyślnie odłączono!");
        } else {
            System.err.println("-- Połączenie nie zostało otwarte!");
        }
    }

    public Connection getConnection() {
        return connection;
    }    
    
    @Override
    protected void finalize() throws Throwable {
        if (statement != null) {
            if (statement.getResultSet() != null) {
                statement.getResultSet().close();
            }
            statement.close();
        }
        if (connection != null) {
            connection.close();
        }
        super.finalize();
    }

    public void rollback() {
        try {
            statement.executeQuery("ROLLBACK");
        } catch (Exception ex) {
            System.out.println("Nie udalo wykonac sie ROLLBACKa\n"+ex.getLocalizedMessage());
        }
    }
}
